<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";
import { ElMessageBox, ElMessage, UploadUserFile, UploadFile } from "element-plus";
import type { Resource, chapter, ResourceF } from "@/types/resource";
import type { ResourceType } from "@/enums/ResourceEnum";
import ResourceAPI from "@/api/resource/index";

const idLoading = ref(false); // 加载动画

const resType = ["课件", "代码", "书籍"];
const fileList = ref<UploadUserFile[]>([]);
//选择章节
//const selectedChapter = ref<number | undefined>(undefined);
// 收集资源数据
const resourcesObj = ref<Resource>({
  id: 0,
  name: "",
  type: "课件" as ResourceType,
  chapter: "",
  date: "",
  file: new Blob(),
});
//选择章节
// const selectChapter = (chapterId?: number) => {
//   selectedChapter.value = chapterId;
//   getResourceList();
// };
// 资源数据
const resources = ref<Resource[]>([]);
const chapters = ref<chapter[]>([
  {
    sectionId: 0,
    sectionName: "全部",
  },
  {
    sectionId: 1,
    sectionName: "第一章",
  },
  {
    sectionId: 2,
    sectionName: "第二章",
  },
  {
    sectionId: 3,
    sectionName: "第三章",
  },
  {
    sectionId: 4,
    sectionName: "第四章",
  },
  {
    sectionId: 5,
    sectionName: "第五章",
  },
  {
    sectionId: 6,
    sectionName: "第六章",
  },
  {
    sectionId: 7,
    sectionName: "第七章",
  },
  {
    sectionId: 8,
    sectionName: "第八章",
  },
  {
    sectionId: 9,
    sectionName: "第九章",
  },
  {
    sectionId: 10,
    sectionName: "第十章",
  },
]);

// 章节选择变量
const selectSectionId = ref<number>(0);

const handleChangeChapter = () => {
  getResourceList();
};
// 表单实力
const formRef = ref();
// 获取资源列表
const getResourceList = async () => {
  idLoading.value = true;
  const data = await ResourceAPI.getResourceList(selectSectionId.value);
  const mapData = data.map((item: ResourceF) => {
    return {
      id: item.id,
      name: item.resourceName,
      type: item.resourceType,
      chapter: `第${item.sectionId}章`,
      date: formatDate(item.time),
      file: item.address,
    };
  });

  // 更新 resources 变量的值
  resources.value = mapData;
  idLoading.value = false;
};
getResourceList();

// 控制上传对话框的显示与隐藏
const uploadDialogVisible = ref(false);
// 是否正在上传
const uploading = ref(false);
// 上传进度
const progress = ref(0);

// 表单校验
const rules = ref({
  name: [{ required: true, message: "请输入资源名称", trigger: "blur" }],
  type: [{ required: true, message: "请选择资源类型", trigger: "change" }],
  chapter: [{ required: true, message: "请选择资源章节", trigger: "blur" }],
  file: [{ required: true, message: "请上传资源文件", trigger: "blur" }],
});

// 添加上传前校验
const beforeUpload = (file: File) => {
  //上传资源类型
  const validTypes = [
    "application/pdf",
    "application/vnd.ms-powerpoint", // ppt
    "application/vnd.openxmlformats-officedocument.presentationml.presentation", // pptx
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // docx
    "image/jpeg", // jpg, jpeg
    "image/jpg",
    "image/png", //  png 格式
    "application/zip",
    "application/x-zip-compressed", // zip
  ];
  // 计算文件大小
  const fileSize = Math.floor(file.size / 1024 / 1024);
  const isAllowed = validTypes.includes(file.type) && fileSize < 100;
  if (!isAllowed) {
    ElMessage.error("仅支持 PDF/Word/压缩包/jpg 格式，且文件大小不能超过 100MB");
  }
  return isAllowed;
};

// 上传文件数量超过限制时的回调函数
const handleExceed = () => {
  ElMessage.warning("只能上传一个文件");
};

// 删除按钮点击事件
const handleDelete = (id: number) => {
  ElMessageBox.confirm("确定要删除该资源吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      await ResourceAPI.deleteResource(id);
      // 重新获取资源列表
      await getResourceList();
      ElMessage.success("删除成功");
    })
    .catch(() => {
      ElMessage.info("已取消删除");
    });
};

// 将row对象中的file属性转换为File对象
async function urlToFile(url: string, fileName: string) {
  try {
    const response = await axios.get(url, { responseType: "arraybuffer" });
    const data = response.data;
    const blob = new Blob([data], {
      type: response.headers["content-type"],
    });
    const file = new File([blob], fileName, { type: blob.type });
    return file;
  } catch (error) {
    console.error("转换为File对象时发生错误:", error);
    throw error;
  }
}

// 更新按钮点击事件
const handleUpdate = (row: Resource) => {
  nextTick(() => {
    formRef.value && formRef.value.clearValidate();
  });
  Object.assign(resourcesObj.value, JSON.parse(JSON.stringify(row)));
  // 清空文件列表
  fileList.value = [];
  if (row.file) {
    // 模拟文件信息
    fileList.value.push({
      name: row.name,
      url: row.file,
      uid: Number(row.id),
    } as unknown as UploadUserFile);
  }
  uploadDialogVisible.value = true;
};

// 上传按钮点击事件
const handleUpload = async () => {
  // 清除表单校验信息
  nextTick(() => {
    formRef.value && formRef.value.clearValidate();
  });
  fileList.value = [];
  // 每次上传前先清空数据
  Object.assign(resourcesObj.value, {
    id: 0,
    name: "",
    type: "课件" as ResourceType,
    chapter: "",
    date: "",
    file: null,
  });
  uploadDialogVisible.value = true;
};

// 上传文件改变事件
const handleChange = (file: UploadFile) => {
  resourcesObj.value.file = file.raw as File;
};

// 取消上传请求的逻辑
const controller = new AbortController();

// 上传保存按钮点击事件
const handleSaveUpload = async () => {
  // 先进行表单校验
  await formRef.value.validate();

  // 校验通过后执行上传
  uploading.value = true;
  // 上传时间
  resourcesObj.value.date = formatDate(new Date().toISOString());

  // 处理文件数据
  const fd = new FormData();
  if (resourcesObj.value.file instanceof File) {
    fd.append("file", resourcesObj.value.file);
  } else {
    const res: File = await urlToFile(resourcesObj.value.file as string, resourcesObj.value.name);
    resourcesObj.value.file = res;
    fd.append("file", resourcesObj.value.file);
  }
  // 处理章节数据 第1章/第一章处理成 对应数字1，2，
  if (typeof resourcesObj.value.chapter != "number") {
    resourcesObj.value.chapter = Number(
      resourcesObj.value.chapter.replace("第", "").replace("章", "")
    );
  }
  try {
    const signal = controller.signal;
    await ResourceAPI.addOrUpdateResource(resourcesObj.value, fd, signal);
    await getResourceList();
    ElMessage.success(resourcesObj.value.id ? "资源更新成功" : "资源上传成功");
  } catch (error) {
    console.error("资源上传失败:", error);
  }
  uploadDialogVisible.value = false;
  uploading.value = false;
};
// 下载按钮点击事件
const handleDownload = async (row: Resource) => {
  try {
    // 调用后端接口获取文件流
    const response = await ResourceAPI.downloadResource(row.id as number);
    // 创建一个 Blob 对象
    const blob = new Blob([await response.data], {
      type: response.headers["content-type"],
    });
    // 创建一个下载链接并触发下载
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = row.name;
    a.click();
    window.URL.revokeObjectURL(url);
  } catch (error) {
    console.error("文件下载失败:", error);
    ElMessage.error("文件下载失败，请稍后重试");
  }
};

// 表单取消回调
const handleCancel = () => {
  uploadDialogVisible.value = false;
  // 重置表单
  formRef.value && formRef.value.resetFields();
  // 如果有上传的请求，则取消上传请求
  if (uploading.value) {
    controller.abort();
    uploading.value = false;
    ElMessage.info("上传已取消");
  }
};
// 日期格式处理函数
const formatDate = (date: string) => {
  const dateObj = new Date(date);
  const year = dateObj.getFullYear();
  const month = (dateObj.getMonth() + 1).toString().padStart(2, "0");
  const day = dateObj.getDate().toString().padStart(2, "0");
  return `${year}-${month}-${day}`;
};
</script>

<template>
  <div class="main">
    <el-card v-loading="idLoading">
      <!-- 上传按钮 -->
      <el-form-item>
        <el-button type="primary" icon="Upload" @click="handleUpload">上传资源</el-button>
      </el-form-item>
      <el-form-item label="选择章节">
        <el-select v-model="selectSectionId" style="width: 200px" @change="handleChangeChapter">
          <el-option
            v-for="item in chapters"
            :key="item.sectionId"
            :label="item.sectionName"
            :value="item.sectionId ?? ''"
          ></el-option>
        </el-select>
      </el-form-item>
      <!-- 资源表格 -->
      <el-table :data="resources" style="margin-top: 20px" border>
        <el-table-column prop="name" label="资源名称" />
        <el-table-column prop="type" label="资源类型" />
        <el-table-column prop="chapter" label="所属章节" />
        <el-table-column prop="date" label="上传日期" />
        <el-table-column label="操作">
          <template #default="{ row }">
            <el-button type="danger" size="small" @click="handleDelete(row.id)">删除</el-button>
            <el-button type="primary" size="small" @click="handleUpdate(row)">更新</el-button>
            <el-button size="small" @click="handleDownload(row)">下载</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 上传对话框 -->
      <el-dialog
        v-model="uploadDialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        title="教学资源上传"
        width="50%"
      >
        <el-form ref="formRef" :model="resourcesObj" :rules="rules" label-width="100px">
          <el-form-item label="资源名称" prop="name" required>
            <el-input
              v-model="resourcesObj.name"
              placeholder="请输入资源名称（例：指针应用讲义）"
            />
          </el-form-item>

          <el-form-item label="资源类型" prop="type" required>
            <el-select v-model="resourcesObj.type" placeholder="请选择类型">
              <el-option v-for="type in resType" :key="type" :label="type" :value="type" />
            </el-select>
          </el-form-item>

          <el-form-item label="所属章节" prop="chapter" required>
            <el-select v-model="resourcesObj.chapter">
              <el-option
                v-for="item in chapters"
                :key="item.sectionId"
                :label="item.sectionName"
                :value="item.sectionId ?? ''"
              />
            </el-select>
          </el-form-item>

          <el-form-item label="文件上传" prop="file" required>
            <el-upload
              v-model="resourcesObj.file"
              drag
              :auto-upload="false"
              :on-change="handleChange"
              :before-upload="beforeUpload"
              :on-exceed="handleExceed"
              :limit="1"
              class="upload-area"
              :file-list="fileList"
            >
              <el-icon><UploadFilled /></el-icon>
              <div class="el-upload__text">
                将文件拖到此处或
                <em>点击上传</em>
                <br />
                <span class="tip">支持格式：PDF/DOC/ZIP/png/jpeg/jpg</span>
              </div>
            </el-upload>
            <el-progress
              v-show="progress > 0"
              :text-inside="true"
              :percentage="progress"
              :stroke-width="15"
              :status="progress < 100 ? 'success' : ''"
              class="progress-bar"
            />
          </el-form-item>
        </el-form>

        <template #footer>
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" :disabled="uploading" @click="handleSaveUpload">
            {{ uploading ? "上传中..." : "开始上传" }}
          </el-button>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<style scoped lang="scss">
.main {
  padding: 20px;
  .el-button {
    margin-right: 10px;
  }
}
.upload-area {
  width: 100%;
  :deep(.el-upload) {
    width: 100%;
    .el-upload-dragger {
      padding: 40px;
      .tip {
        font-size: 12px;
        color: #999;
      }
    }
  }
}
.progress-bar {
  margin-top: 15px;
}
</style>
